package simplepushclient;

import java.io.*;
import java.net.*;
/**
 * Used for waking up computers
 *
 * @author dave
 * @since 9 Apr 2009 08:00:04
 */
public class WakeOnLan {

    public static final int PORT = 9;
    /**
     * Send a Wake On LAN magic packet to ip and mac address specifed
     *
     * @param ip
     * @param macAddress
     */
    public static void wakeup(String ip, String macAddress) {
        if (ip == null || ip.length() < 1)
            throw new IllegalArgumentException(
                          "ip address cannot be null or blank");
        if (macAddress == null || macAddress.length() < 1)
            throw new IllegalArgumentException(
                          "macAddress cannot be null or blank");

        byte[] macBytes = getMacBytes(macAddress);
        byte[] bytes = new byte[6 + 16 * macBytes.length];
        for (int i = 0; i < 6; i++) {
            bytes[i] = (byte) 0xff;
        }
        for (int i = 6; i < bytes.length; i += macBytes.length) {
            System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
        }

        DatagramSocket socket = null;
        try {
            InetAddress address = InetAddress.getByName(ip);
            DatagramPacket packet =
                new DatagramPacket(bytes, bytes.length, address, PORT);

            if (true) {
                System.out.println("Sending datagram (UDP) packet to ip["
                                   + address + "] on port[" + PORT + "]");
                System.out.println("Message bytes [" + bytes + "]");
            }

            socket = new DatagramSocket();
            socket.send(packet);
            System.out.println("Wake-on-LAN packet sent.");
            return;
        } catch (UnknownHostException e) {
            System.out.println(e);
        } catch (SocketException e) {
            System.out.println(e);
        } catch (IOException e) {
            System.out.println(e);
        } finally {
            if (socket != null && !socket.isClosed()) {
                socket.close();
            }
        }
    }

    private static byte[] getMacBytes(String macStr)
                                     throws IllegalArgumentException {
        byte[] bytes = new byte[6];
        String[] hex = macStr.split("(\\:|\\-)");
        if (hex.length != 6) {
            throw new IllegalArgumentException("Invalid MAC address.");
        }
        try {
            for (int i = 0; i < 6; i++) {
                bytes[i] = (byte) Integer.parseInt(hex[i], 16);
            }
        } catch (NumberFormatException e) {
            throw new IllegalArgumentException(
                                "Invalid hex digit in MAC address.");
        }
        return bytes;
    }

}
